#include "lexer.h"

%%{
    machine lexer;

    action A_newLine    {line++; lastNewline = p;}

    white               = (("\n")@A_newLine | space);


    identifier          = ([a-zA-Z]|'_')([a-zA-Z0-9]|'_')*;
    integer             = ('+'|'-')?[0-9]+;
    whitespace          = white+;


    main := |*

        'struct'        => { createToken(Token::Struct); fbreak;};
        'new'           => { createToken(Token::New); fbreak;};
        'return'        => { createToken(Token::Return); fbreak;};
        'if'            => { createToken(Token::If); fbreak;};
        'else'          => { createToken(Token::Else); fbreak;};
        'while'         => { createToken(Token::While); fbreak;};
        'for'           => { createToken(Token::For); fbreak;};


        identifier      => { createToken(Token::Identifier); fbreak;};
        integer         => { createToken(Token::Integer); fbreak;};


        whitespace      => { skipToken();};

        any             => { createToken(Token::LexerError); fbreak;};
    *|;

}%%

namespace ragelInternal
{
    %% write data;
}

using namespace ragelInternal;

void Lexer::init(const char* input, uint32_t len)
{
    %% write init;

    lastRow = 1;

    p = (char*)input;
    tokenStart = p;
    pe = p + len; /* pe points to 1 byte beyond the end of this block of data */
    //const char* eof = is_eof ? pe : ((char*) 0); /* Indicates the end of all data, 0 if not in this block */
    eof = pe;
    lastNewline = p-1;
    line = 1;
}

Token Lexer::nextToken()
{
    outToken.type = Token::Eof;

//    if (p>=pe)
//    {
//        return createToken(TokenType::Eof);
//    }

    %% write exec;

    return outToken;
}

